/**
 * @constructor
 * @param {string} name
 * @param {number} index
 * @param {boolean} sync
 */
function Portfolio(name, index, sync) {
  this.name = name;
  this.index = index;
  this.quotes = [];
  this.$table;
  this.sync = sync;
}

/**
 * Adds a quote to the portfolio
 * @param {Quote} quote
 * @returns The current object
 * @type Portfolio
 */
Portfolio.prototype.add = function(quote) {
  this.quotes.push(quote);
	return this;
};

/**
 * Draws the table used in the popup
 * @param {Object} contextNode
 * @returns The current object
 * @type Portfolio
 */
Portfolio.prototype.drawTable = function(contextNode) {
	$(contextNode).empty();

  var $table = $('<table>');
  var $thead = $('<thead>');
  var $tbody = $('<tbody>');
  var $tfoot = $('<tfoot>');
  var $theadTr = $('<tr>');
  var $tfootTr = $('<tr>');

  for (var i = 0; i < Metrics.count(); i++) {
		$theadTr = $theadTr.append($('<td>').text(Localizer.translate(Metrics.column(i))));
  }
	$thead.append($theadTr);
  
  for (var i = 0; i < this.quotes.length; i++) {
    $tbody.append($(this.quotes[i].drawRow()));
  }

  for (var i = 0; i < Metrics.count(); i++) {
    var $td = $('<td>');
    var metric = Metrics.get(Metrics.column(i));

    if (metric.numer != undefined) {
      var numer = 0;
      var denom = (metric.denom == undefined ? 1 : 0);
      for (var j = 0; j < this.quotes.length; j++) {
        numer += metric.numer.call(this.quotes[j]);
        if (metric.denom != undefined) {
          denom += metric.denom.call(this.quotes[j]);
        }
        if (Metrics.column(i) === "portChange") {
          alert(numer + "\n" + denom + "\n" + this.quotes[j].secid);
        }
      }
      $td = $(this.quotes[0].append.call({"decimals": 2}, numer/denom, metric.type));
    }

    $tfootTr.append($td);
  }
  $tfoot.append($tfootTr);
  
  $(contextNode).append($table.append($thead).append($tbody).append($tfoot));
	return this;
};

Portfolio.prototype.editTable = function(contextNode) {
	$(contextNode).empty();
  
  var $table = $('<table>');
  var $thead = $('<thead>');
  var $tbody = $('<tbody>');
  var headers = ['index', 'secid', 'source', 'count', 'pricePaid', 'decimals', 'trigger'];
  var $theadTr = $('<tr>');
  
	$.each(headers, function(index, header){
    $theadTr.append($('<th>').text(Localizer.translate(header)));
	});
  $thead.append($theadTr);

  for (var i = 0; i < this.quotes.length; i++) {
    $tbody.append(this.addRow(this.quotes[i], i));
  }
  $tbody.append(this.addRow(new Quote("", "bloomberg", 0, 0, 2, ""), i));
  
  $(contextNode).append($table.append($thead).append($tbody));

	// Currently not working
  $tbody.last().children('input:first').focus();
  this.$table = $table;
	return this;
};

Portfolio.prototype.addRow = function(quote, i) {
	var valueCell = function(value, maxWidth){
		return $('<td>').append($('<input>').addClass('value').attr('type', 'text')
			.css('max-width', (maxWidth !== undefined ? maxWidth : 'auto')).val(value));
	}
  var $tr = $('<tr>');

	// # column
  $tr.append($('<td>').text(i).addClass('value'));
  
  var secidTd = document.createElement("td");
  var secidInput = document.createElement("input");
  var _this = this;
  secidInput.type = "text";
  secidInput.value = quote.secid;
  secidInput.onblur = function(e) {
    var secidTr = e.srcElement.parentNode.parentNode;
    if (e.srcElement.value === "") {
      secidTr.nextSibling.getElementsByTagName("input")[0].focus();
      secidTr.parentNode.removeChild(secidTr);
    } else if (secidTr.nextSibling == null) {
      secidTr.parentNode.appendChild(_this.addRow(new Quote("", "bloomberg", 0, 0, 2, ""), i + 1));
    }
  };
  secidTd.appendChild(secidInput);
  $tr.append($(secidTd));
  
	// Source column
	$tr.append($('<td>').append($(Sources.selection(quote.source))));
	
	// Value columns
	$tr.append(valueCell(quote.count));
  $tr.append(valueCell(quote.pricePaid));
	$tr.append(valueCell(quote.decimals));
	$tr.append(valueCell(quote.trigger, '20em'));
  
  return $tr;
};

/**
 * 
 * @param {Object} contextNode
 */
Portfolio.prototype.updateTable = function(contextNode) {
  // Highlight cells with changing values
  var highlight = function(td, rgb, pct) {
    if (pct > 1) {
      pct = 1;
    }
    var color = "#";
    for (var k = 0; k < rgb.length; k++) {
      var x = Math.round(255 - (255 - rgb[k]) * (1 - pct));
      if (x <= 15) {
        color += "0";
      }
      color += x.toString(16);
    }
    td.style.backgroundColor = color;
    if (pct < 1) {
      setTimeout(function() { highlight(td, rgb, pct + 0.1); }, 100);
    }
  };
  
  var trs = contextNode.getElementsByTagName("tbody")[0].getElementsByTagName("tr");
  
  for (var i = 0; i < trs.length; i++) {
    var tds = trs[i].getElementsByTagName("td");
    for (var j = 0; j < tds.length; j++) {
      var metric = Metrics.column(j);
      var data = this.quotes[i].get(metric);
      var type = Metrics.get(metric).type;
      var td = this.quotes[i].append(data, type);

      // Highlight if different
      if (type !== "text") {
        var valNew = parseFloat(td.textContent.replace("―", "0"));
        var valOld = parseFloat(tds[j].textContent.replace("―", "0"));
        trs[i].replaceChild(td, tds[j]);
        if (valNew > valOld) {
          highlight.call(null, td, [172, 244, 172], 0);
        } else if (valNew < valOld) {
          highlight.call(null, td, [255, 206, 190], 0);
        }
      } else {
        trs[i].replaceChild(td, tds[j]);
      }
    }
  }
  
  var tds = contextNode.getElementsByTagName("tfoot")[0].getElementsByTagName("td");
  
  for (var i = 0; i < tds.length; i++) {
    var metric = Metrics.get(Metrics.column(i));

    if (metric.numer != undefined) {
      var numer = 0;
      var denom = (metric.denom == undefined ? 1 : 0);
      for (var j = 0; j < this.quotes.length; j++) {
        numer += metric.numer.call(this.quotes[j]);
        if (metric.denom != undefined) {
          denom += metric.denom.call(this.quotes[j]);
        }
      }
      var td = this.quotes[0].append.call({"decimals": 2}, numer/denom, metric.type);
      var valNew = parseFloat(td.textContent.replace("―", "0"));
      var valOld = parseFloat(tds[i].textContent.replace("―", "0"));
      tds[i].parentNode.replaceChild(td, tds[i]);
      if (valNew > valOld) {
        highlight.call(null, td, [172, 244, 172], 0);
      } else if (valNew < valOld) {
        highlight.call(null, td, [255, 206, 190], 0);
      }
    }
  }
};

/**
 * Update the quotes in the table that's been drawn
 * @param {Object} contextNode
 * @returns The current object
 * @type Portfolio
 */
Portfolio.prototype.updateQuotes = function(contextNode) {
  var trs = contextNode.getElementsByTagName("tbody")[0].getElementsByTagName("tr");
  var temp = [];

  for (var i = 0; i < trs.length; i++) {
    var inputs = trs[i].getElementsByTagName("input");

    // Ignore blank rows
    if (inputs[0].value !== "") {
      var q = new Quote(inputs[0].value, inputs[1].value, inputs[2].value, inputs[3].value, inputs[4].value, inputs[5].value);
      temp.push(q);
    }
  }
  this.quotes = temp;
	return this;
};

function highlight(td, rgb, pct) {
  if (pct > 1) {
    pct = 1;
  }
  var color = "#";
  for (var k = 0; k < rgb.length; k++) {
    var x = Math.round(255 - (255 - rgb[k]) * (1 - pct));
    if (x <= 15) {
      color += "0";
    }
    color += x.toString(16);
  }
  td.style.backgroundColor = color;
  if (pct < 1) {
    setTimeout(function() { highlight(td, rgb, pct + 0.1); }, 100);
  }
}